import native from 'libohosdevice.so';

/**
 * 初始化RFID模块
 * @param path 指定RFID模块的设备路径
 * @param uartNum 指定使用的UART编号
 * @returns 返回初始化结果，通常为0表示成功，非0表示失败
 */
export function napi_rfidModuleInit(path: string, uartNum: number): number {
  // 参数校验
  if (typeof path !== 'string' || path.trim() === '') {
    console.error('Invalid path provided.');
    throw new Error('Invalid path provided.');
  }

  // if (typeof uartNum !== 'number' || uartNum < 0) {
  //   console.error('Invalid uartNum provided.');
  //   throw new Error('Invalid uartNum provided.');
  // }

  let result: number = native.jni_rfid_open(path,uartNum);
  return result;
}

/**
 * 关闭RFID设备连接。
 * 
 * 本函数负责调用底层的JNI接口，来关闭RFID设备的连接。在调用之后，应用应该不再能与该设备进行通信。
 * 
 * @returns {number} 返回关闭操作的结果代码，通常为0表示成功，非0表示失败。
 */
export function napi_rfid_close(): number {
  // 调用JNI方法关闭RFID设备连接
  let result: number = native.jni_rfid_close();
  return result;
}

/**
 * 检查RFID卡是否存在。
 * 本函数无参数。
 * 
 * @returns {ArrayBuffer} 返回一个ArrayBuffer类型的结果，具体含义依赖于底层 native 方法的实现。
 */
export function napi_rfid_checkCard(): ArrayBuffer {
  // 调用本地JNI方法进行RFID卡检查
  let result: ArrayBuffer = native.jni_rfid_checkCard();
  return result;
}

/**
 * 从RFID读取指定块索引的数据
 * @param blockIndex 块索引，指定要读取的区块位置
 * @param key 用于读取操作的密钥，以ArrayBuffer形式提供
 * @returns 返回从RFID读取到的数据，以ArrayBuffer形式返回
 */
export function napi_rfid_readBlock(blockIndex: number, key: ArrayBuffer): ArrayBuffer {
  // 参数校验
  if (typeof blockIndex !== 'number'  || blockIndex < 0 || blockIndex > 0xFF) {
    throw new Error('Invalid blockIndex: must be a number.');
  }
  
  if (!(key instanceof ArrayBuffer)) {
    throw new Error('Invalid key: must be an ArrayBuffer.');
  }
  
  let result: ArrayBuffer = native.jni_rfid_readBlock(blockIndex,key);
  return result;

}

/**
 * 从JNI调用获取GPIO引脚值
 * @param gpipNum GPIO引脚编号
 * @returns 返回获取到的GPIO引脚的当前电平值
 */
export function napi_gpio_getValue(gpipNum: number): number {
  // 输入验证
  if (typeof gpipNum !== 'number' || gpipNum < 0 || gpipNum > 1024) {
    console.error('Invalid GPIO number.');
    throw new Error('Invalid input values');
  }

  let result: number = native.jni_gpio_getValue(gpipNum);
  return result;
  }

/**
 * 设置GPIO引脚的状态
 * @param gpipNum GPIO引脚编号，必须为数字，且在有效范围内（例如0-1024）
 * @param gpioStatus 要设置的状态，必须为数字，通常为0或1，表示低电平或高电平
 * @returns 返回操作的结果，通常为0表示成功，非0表示失败
 * @throws 如果输入参数类型不正确或参数值不在有效范围内，则抛出错误
 */
export function napi_gpio_setValue(gpipNum: number, gpioStatus: number): number {
  // 输入验证
  if (typeof gpipNum !== 'number' || typeof gpioStatus !== 'number') {
    console.error('Invalid input types for gpipNum or gpioStatus');
    throw new Error('Invalid input types');
  }

  // 根据实际需求限制输入值的范围
  if (gpipNum < 0 || gpipNum > 1024 || gpioStatus < 0 || gpioStatus > 1) {
    console.error('Invalid input values for gpipNum or gpioStatus');
    throw new Error('Invalid input values');
  }

  let result: number = native.jni_gpio_setValue(gpipNum, gpioStatus); // 调用本地方法设置GPIO状态

  return result;
}

/**
 * 打开串行端口
 * 
 * 本函数用于通过指定的路径打开一个串行端口，并设置该端口的波特率、数据位、停止位和校验位。
 * 
 * @param path 字符串，表示串行端口的路径。
 * @param baudrate 数字，表示串行端口的波特率。
 * @param databits 数字，表示串行端口的数据位数，常见的有5、6、7、8位。
 * @param stopbits 数字，表示串行端口的停止位数，常见的有1、1.5、2位。
 * @param parity 数字，表示串行端口的校验位类型，常见的有无校验、奇校验、偶校验。
 * @returns 返回数字，表示操作的结果，成功通常返回0，失败返回错误码。
 */
export function napi_serial_open(path: string, baudrate: number, databits: number, stopbits: number, parity: number): number {
  // 调用本地方法打开串行端口并设置相关参数
  let result: number = native.jni_serial_open(path, baudrate,databits,stopbits,parity);
  return result;
}

/**
 * 从串行端口读取数据。
 * @param dataLen 要读取的数据长度。
 * @param dataBuf 存储读取数据的ArrayBuffer。
 * @returns 读取操作的结果状态码。
 */
export function napi_serial_read(fd: number,dataLen: number, dataBuf: ArrayBuffer): number {

  // 调用本地JNI方法进行串行数据读取
  let result: number = native.jni_serial_read(fd,dataLen, dataBuf); 

  return result;
}

/**
 * 将数据写入串行端口。
 * 
 * @param dataLen 数据长度，表示要写入的数据的字节数。
 * @param dataBuf 数据缓冲区，包含要写入的数据。
 * @returns 返回执行结果，通常为成功或错误代码。
 */
export function napi_serial_write(fd: number,dataLen: number, dataBuf: ArrayBuffer): number {

  // 调用本地方法进行串行数据写入
  let result: number = native.jni_serial_write(fd,dataLen, dataBuf); 

  return result;
}

/**
 * 调用本地方法进行串行端口轮询
 * @param timeout_ms 轮询超时时间，单位为毫秒
 * @returns 返回轮询结果，具体含义依赖于native.jni_serial_poll的实现
 */
export function napi_serial_poll(fd: number,timeout_ms: number): number {

  // 调用本地方法设置GPIO状态
  let result: number = native.jni_serial_poll(fd,timeout_ms);

  return result;
}

/**
 * 关闭串行通信接口
 * 该函数无参数和返回值，主要用于调用本地JNI方法以关闭串行通信接口。
 */
export function napi_serial_close(fd: number) {
  native.jni_serial_close(fd); // 调用本地JNI方法关闭串行通信接口
}